﻿
package we3d.samples.boxGrid {
	
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.*;
	
	import we3d.rasterizer.IRasterizer;
	import we3d.rasterizer.ScanlineFlat;
	import we3d.rasterizer.ScanlineFlatLight;
	import we3d.rasterizer.NativeFlatLight;
	import we3d.rasterizer.NativeFlat;
	
	import we3d.View3d;
	import we3d.Scene3d;
	import we3d.scene.SceneObject;
	import we3d.material.Surface;
	import we3d.modeler.create.SimpleBoxTool;
	import we3d.animation.PropertyAnimator;
	import we3d.material.FlatLightAttributes;
	import we3d.material.FlatAttributes;
	
	import we3d.layer.GradientBackdrop;
	
	import we3d.core.transform.Transform3d;
	import we3d.core.transform.All;
	
	import we3d.scene.SceneLight;
	import we3d.scene.LightGlobals;
	
	import we3d.core.culling.BoxCulling;
	import we3d.core.culling.SphereConeCulling;
	import we3d.renderer.realistic.ClipFrustum;
	
	public class BoxGridMain {
		
		public function BoxGridMain () {}
		
		public var boxW:Number = 155;
		public var boxH:Number = 155;
		public var boxD:Number = 155;

		public var boxCols:Number = 148;
		public var boxRows:Number = 148;

		public var colSpace:Number = 800;
		public var rowSpace:Number = 800;

		public var scene:Scene3d;
		public var view:View3d;
		public var rasterizer:IRasterizer;
		public var atbs:FlatAttributes;
		public var engineTarget:Sprite;
		
		public var speed:Number = 20;
		public var acel:Number = 1.09;
		public var decel:Number = 1.05;
		private var spd:Number = 0;
		
		private var mdown:Boolean=false;
		private var pressX=0; var pressY:Number=0;
		
		public function createScene (drawTarget:Sprite) :void {
			
			engineTarget = drawTarget;
			
			scene = new Scene3d();
			view = new View3d(550, 400);
			view.scene = scene;
			//view.renderer = new ClipFrustum();
			
			engineTarget.addChild (view.viewport);
			
			scene.cam.initProjection(60*Math.PI/180, 1, 53580, 550, 400);
			
			view.firstLayer.backdrop = new GradientBackdrop(0x000000, 0x777777, 0x777777, 0x90b0ce, 30, 120);
			
			var lg:LightGlobals = new LightGlobals();
			
			lg.ambientColor = 0x90b0ce;
			lg.ambientLight = 0.25;
			
			lg.lightList.push( new SceneLight(true) );
			lg.lightList[0].color = 0x90b0ce;
			lg.lightList[0].intensity = 0.25;
			lg.lightList[0].transform.setPosition( 0, -60 * 255, 0 );
			
			view.addFilter( lg );
			
			rasterizer = new ScanlineFlat();
			//rasterizer = new NativeFlat();
			//rasterizer = new ScanlineFlatLight();
			
			atbs = new FlatAttributes(0x4e6191, 1);
			//atbs = new FlatLightAttributes(0x4e6191, 1, 0.1, 0.8, lg);
			
			
			scene.cam.transform.rotationX = 0;
			scene.cam.transform.setPosition(2500, 500, 1000);
			
			createBoxGrid();
			
			engineTarget.stage.addEventListener(Event.ENTER_FRAME, frameLoop);
			engineTarget.stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			engineTarget.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			
			scene.invalidate();
        }
		
		private function mouseDown (evt:Event):void {
			pressX = engineTarget.mouseX;
			pressY = engineTarget.mouseY;
			mdown = true; 
		}
		private function mouseUp (evt:Event) :void { mdown = false; }
		
		private function frameLoop (evt:Event):void {
			
			if(mdown) {
				var rx:Number = (pressY-engineTarget.mouseY)/180;
				var ry:Number = (pressX-engineTarget.mouseX)/180;
				
				scene.cam.transform.rotationX -= rx;
				scene.cam.transform.rotationY -= ry;
				
				pressX = engineTarget.mouseX;
				pressY = engineTarget.mouseY;
				
				if(spd < 0.5) spd = acel;
				if(spd < speed) spd *= acel;
				if(spd > speed) spd = speed;
				
				scene.invalidate();
			}
			else
			{
				pressX = engineTarget.mouseX;
			}
			
			if(spd > 0) 
			{
				scene.cam.transform.moveOnAxis(scene.cam.transform.zAxis, spd);
				spd /= decel;
				
				scene.invalidate();
			}
			
		}
		
		private function createBoxGrid () :void {
			var i:Number;
			var j:Number;
			for(i=0; i<boxRows; i++) {
				for(j=0; j<boxCols; j++) {
					scene.objectList.push( createBox(i, j) );
				}
			}
		}
		
		private function createBox (i:Number, j:Number) :SceneObject {
			
			var sf:Surface = new Surface(rasterizer, atbs);
			sf.hideBackfaces = true;
			
			var box:SceneObject = new SceneObject();
			box.objectCuller = new BoxCulling();
			
			var r20:Number = Math.random()*200;
			
			SimpleBoxTool.create(box, sf, 
						{x:  boxW/2, 	y:  boxH/2, 	z:  boxD/2},
						{x: -boxW/2, 	y: -boxH/2,   	z: -boxD/2}, 
						true, true, null, false);
			
			var tr:Transform3d = box.transform as Transform3d;
			
			tr.x = j * (boxW+colSpace) + r20;
			tr.y = r20*r20;
			tr.z = i * (boxD+rowSpace) + r20;
			
			box.fastInit = true;
			
			return box;
		}
		
	}
}